package cn.gyn.gynrpc.core.cluster;

import cn.gyn.gynrpc.core.api.LoadBalancer;

import java.util.List;
import java.util.Random;

/**
 * 随机负载均衡，万次的调用平均误差不超过1%，如果要完全平均，可以用轮询机制，除此之外，还有权重weightedRR算法、自适应AAWR算法
 * 权重算法举例：
 * 比如有俩服务，8081权重设为100，8082权重设为300，也就是100个调用里，理想状况有25个去8081，75个却8082
 * 具体实现：取0-99的随机数，当随机结果<25时，取8081，else取8082
 *
 * 自适应算法（又叫基于活动时间窗口的占用平均）：
 * "基于活动时间窗口的占用平均" 是指在一定时间内资源的占用情况。例如，对于计算机网络或者服务器的资源占用情况，可以通过记录一定时间内的资源使用情况，然后计算平均值来评估资源的使用情况。这种方法可以帮助评估系统的资源利用率，从而进行负载均衡。
 * 解释：当我们不知道服务器性能如何，通过自适应方式给能力好的多分配权重， 能力差的少分配权重
 * 自适应算法举例：
 * 记录接口响应时长，仍以8081为例，假设其平均响应时间为10ms，最近一次调用的响应时间为300ms（突然变慢了）;8082avg为100ms，last为90ms
 * 那么我们计算8081分配权重为，10*0.3+300*0.7=w8081;而8082分配的权重为100*0.3+90*0.7=w8082
 * 既要考虑平均响应性能的同时，又要兼顾机器最新的性能状况
 * 当然这里的计算公式内平均响应的处理也有很多细节有待深究。
 */
public class RandomLoadBalancer<T> implements LoadBalancer<T> {
    Random random = new Random();
    @Override
    public T choose(List<T> providers) {
        if (providers == null || providers.size() == 0) return null;
        //这句也能稍微提升一点性能
        if (providers.size() == 1) return providers.get(0);
        //random.nextInt(9) 生成一个范围在 0 到 9 之间（不包括9）的随机整数
        return providers.get(random.nextInt(providers.size()));
    }
}
